import os
import md5
import os.path
import imp
import traceback
import sys
import time
import threading
import sqlite3

from threading import Thread, Event
from Queue import Queue

extension = None

CONN = sqlite3.connect(os.path.expanduser(os.path.join("~","db","plugins.db")))
C = CONN.cursor()
STARTED = "started"


operations = {}

def filter_plugins(plugin_list):
    r = filter(lambda x:x.endswith(".py"),plugin_list)
    r = filter(lambda x:x != "__init__.py",r)
    r = filter(lambda x: not x.endswith("_config.py"),r)
    r = map(lambda x:x[:-3],r)
    value_set = tuple(r)
    return value_set



def order_plugins_by_sequence(plugin_list):
    value_set = filter_plugins(plugin_list)
    sql = "select * from plugins where name in ({0}) order BY SEQUENCE".format(",".join(['?' for x in range(1,len(value_set)+1)]))
    C.execute(sql,value_set)
    r = [x[0]+".py" for x in C]
    return r

def update_state(plugin_name,state):
    C.execute("update plugins set state=(?) where name=(?)",(state,plugin_name))
    CONN.commit()


def load_all(server, parent, plugins_folder):
    if plugins_folder == None:
        return
    print os.path.abspath(plugins_folder)
    for root,directory,plugin_files in os.walk(plugins_folder):
        r = order_plugins_by_sequence(plugin_files)
        for plugin_file in r:
            plugin_file_name = os.path.join(os.getcwd(),root,plugin_file)        
            if plugin_file_name.endswith(".py"):
                print "Parent...{0}".format(__name__)
                print "Loading... {0} ".format(plugin_file_name)
                load_plugin(server, parent, plugin_file_name)
        del directory[:]

    return operations

def add_path(path):
    sys.path.insert(0,path)

def load_module(code_path):
    try:
        try:
            code_dir = os.path.dirname(code_path)
            code_file = os.path.basename(code_path)

            fin = open(code_path, 'rb')

            return  imp.load_source(md5.new(code_path).hexdigest(), code_path, fin)
        finally:
            try: fin.close()
            except: pass
    except ImportError, x:
        print sys.path
        traceback.print_exc(file = sys.stderr)
        raise
    except:
        print sys.path
        traceback.print_exc(file = sys.stderr)
        raise


def start_plugin(server,parent,op):
    if hasattr(operations[op],"start") == False:
        return False
    return operations[op].start(server,parent)

def load_plugin(server, parent, op_path):
    op_name = os.path.basename(op_path)
    if op_name == "config.py" or op_name == "__init__.py":
        return
    operation = op_name[:op_name.rfind(os.path.extsep)]
    operations[operation] = load_module(op_path)
    start_plugin(server, parent,operation)
